package com.caigou.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.caigou.bean.cms.entity.*;
import com.caigou.bean.cms.param.FrontSurveyParam;
import com.caigou.bean.cms.param.SurveyCatalogParam;
import com.caigou.bean.cms.vo.SurveyFormConfigVO;
import com.caigou.bean.exam.entity.Users;
import com.caigou.component.HttpComponent;
import com.caigou.component.RedisComponent;
import com.caigou.component.RedisObjectComponent;
import com.caigou.enums.ResponseEnum;
import com.caigou.mapper.cms.*;
import com.caigou.pojo.*;
import com.caigou.pojo.SurveyFormStatistics;
import com.caigou.service.ISurveyService;
import com.caigou.service.IUserBaseInfoService;
import com.caigou.service.SurveyCatalogService;
import com.caigou.service.SurveyPermissionService;
import com.caigou.util.DateUtil;
import com.caigou.util.Md5Util;
import com.caigou.util.QRCodeUtils;
import com.caigou.util.Result;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class SurveyCatalogServiceImpl implements SurveyCatalogService {

    @Value("${form.catalog.pc_url}")
    private String pcUrl;
    @Value("${form.catalog.mobile_url}")
    private String mobileUrl;
    @Value("${form.catalog.logo_path_web}")
    private String logoPathWeb;
    @Value("${form.catalog.logo_path_yct}")
    private String logoPathYct;
    @Value("${form.catalog.logo_path_yzb}")
    private String logoPathYzb;
    @Value("${form.catalog.logo_path_ykt}")
    private String logoPathYkt;
    @Value("${form.catalog.dest_path}")
    private String destPath;
    @Value("${form.catalog.domainType}")
    private Integer domainType;
    @Value("${spring.profiles.active}")
    private String activeProfile;// 当前额启动环境

    @Resource
    private QRCodeUtils qrCodeUtils;
    @Resource
    private RedisComponent redisComponent;
    @Resource
    private RedisObjectComponent redisObjectComponent;
    @Resource
    private HttpComponent httpComponent;

    @Resource
    private ISurveyService surveyService;
    @Resource
    private IUserBaseInfoService userBaseInfoService;// 用户信息获取
    @Resource
    private SurveyPermissionService surveyPermissionService;

    @Resource
    private SurveyFormMapper surveyFormMapper;
    @Resource
    private SurveySubmitMapper surveySubmitMapper;
    @Resource
    private SurveyCatalogMapper surveyCatalogMapper;
    @Resource
    private SharePlatformMapper sharePlatformMapper;
    @Resource
    private SurveyQuestionMapper surveyQuestionMapper;
    @Resource
    private SurveyOptionMapper surveyOptionMapper;

    @Override
    public Result loadSurveyCatalogConfigList(SurveyCatalogParam param) {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<CatalogConfigList> list = surveyCatalogMapper.loadSurveyCatalogConfigList(param);
        list.forEach(item -> {
            if (!item.getPlatform().equals("")){
                StringBuilder buffer = new StringBuilder();
                String[] array = item.getPlatform().split(",");
                for (String info: array){
                    switch (info){
                        case "1":
                            buffer.append("官网/");
                            break;
                        case "2":
                            buffer.append("易采通app/");
                            break;
                        case "3":
                            buffer.append("易找标/");
                            break;
                        case "4":
                            buffer.append("易考通/");
                            break;
                    }
                }
                item.setPlatform(buffer.toString());
            }
            // 处理目录发布的平台信息
        });
        PageInfo<CatalogConfigList> pageList = new PageInfo<>(list);
        return Result.success(pageList);
    }

    @Override
    public Result updateSurveyCatalogConfigStatus(SurveyCatalogParam param, Users users) {
        int result = surveyCatalogMapper.updateSurveyCatalogConfigStatus(param.getCatalogId(), param.getStatus());
        log.info("更新目录配置表状态 catalogId={},result={}",param.getCatalogId(),result);
        if (param.getStatus() == 0){
            List<String> formList = surveyCatalogMapper.loadSurveyFormListByList(param.getCatalogId());// 获取原本添加的目录列表，将他们的状态设置为表单状态
            for (String info: formList){
                surveyService.updateSurveyFormConfig(info,0);
                redisObjectComponent.del("form:"+info);// 清除目录详情页接口数据
            }
            // 数据下架的时候清除缓存数据
            redisObjectComponent.del("catalogResult:"+param.getCatalogId());// 清除目录详情页接口数据
            redisObjectComponent.del("catalogConfig:"+param.getCatalogId());// 清除目录页配置数据
        }
        if (result == 1){
            // 保存操作记录
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getCatalogId());
            operationLog.setDataType(2);
            operationLog.setUserId(users.getUserid());
            operationLog.setActionType(param.getStatus() == 1 ? 3 : 4);
            operationLog.setActionName(param.getStatus() == 1 ? "启用目录页" : "禁用目录页");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        }
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result deleteSurveyCatalogConfig(SurveyCatalogParam param, Users users) {
        // 判定目录状态是否为-1
        int isCanDelete = surveyCatalogMapper.loadCatalogIsCanDelete(param.getCatalogId(), 0);
        if (isCanDelete == 0) return Result.error(ResponseEnum.CATALOG_DELETE_ERROR);
        // 进行逻辑删除
        int result = surveyCatalogMapper.updateSurveyCatalogConfigStatus(param.getCatalogId(), -1);
        // 数据下架的时候清除缓存数据
        redisObjectComponent.del("catalogResult:"+param.getCatalogId());// 清除目录详情页接口数据
        redisObjectComponent.del("catalogConfig:"+param.getCatalogId());// 清除目录页配置数据
        log.info("逻辑删除目录配置表数据 catalogId={},result={}",param.getCatalogId(),result);
        if (result == 1){
            // 保存操作记录
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getCatalogId());
            operationLog.setDataType(2);
            operationLog.setUserId(users.getUserid());
            operationLog.setActionType(5);
            operationLog.setActionName("删除目录页");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        }
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
    public Result saveSurveyCatalogConfig(SurveyCatalogParam param, Users users) {
        int exist = surveyCatalogMapper.loadCatalogIsExist(param.getCatalogId());
        log.info("获取新增的目录ID是否存在， result={}, catalogId={}",exist,param.getCatalogId());
        if (exist != 0) return Result.error(ResponseEnum.CATALOG_EXIST_ERROR);
        SurveyCatalogConfig catalogConfig = new SurveyCatalogConfig();
        catalogConfig.setCatalogId(param.getCatalogId());
        catalogConfig.setUserId(users.getUserid());
        catalogConfig.setBannerStatus(param.getBannerStatus());
        catalogConfig.setBannerUrl(param.getBannerUrl());
        catalogConfig.setTitle(param.getTitle());
        catalogConfig.setInfoStatus(param.getInfoStatus());
        catalogConfig.setInfoType(param.getInfoType());
        catalogConfig.setInfo(param.getInfo());
        catalogConfig.setConfigType(param.getConfigType());
        catalogConfig.setAuthType(param.getAuthType());
        catalogConfig.setFillType(param.getFillType());
        catalogConfig.setUpdateType(param.getUpdateType());
        catalogConfig.setAuthCodeStatus(param.getAuthCodeStatus());
        catalogConfig.setAuthCode(param.getAuthCode());
        catalogConfig.setAuthUserStatus(param.getAuthUserStatus());
        catalogConfig.setAuthUserErr(param.getAuthUserErr());
        catalogConfig.setTimeStatus(param.getTimeStatus());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            catalogConfig.setStartTime((null == param.getStartTime() || ("").equals(param.getStartTime())) ? null : simpleDateFormat.parse(param.getStartTime()));
            catalogConfig.setEndTime((null == param.getEndTime() || ("").equals(param.getEndTime())) ? null : simpleDateFormat.parse(param.getEndTime()));
        } catch (ParseException e){
            catalogConfig.setStartTime(null);
            catalogConfig.setEndTime(null);
            log.error(e.getMessage());
        }
        catalogConfig.setStartTimeErr(param.getStartTimeErr());
        catalogConfig.setEndTimeErr(param.getEndTimeErr());
        catalogConfig.setCatalogStatus(param.getCatalogStatus());
        catalogConfig.setReleasePlatform(param.getReleasePlatform());
        catalogConfig.setWebPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=1&platform=1");
        catalogConfig.setWebMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=1&platform=4");
        try {
            catalogConfig.setWebQrCode(qrCodeUtils.encode(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=1&platform=4",logoPathWeb,destPath,"web-qurCode-"+param.getCatalogId(),true));
        } catch (Exception e) {
            log.error("生成官网二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setWebQrCodeTitle(param.getWebQrCodeTitle());
        catalogConfig.setYctPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=2&platform=1");
        catalogConfig.setYctMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=2&platform=4");
        try {
            catalogConfig.setYctQrCode(qrCodeUtils.encode(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=2&platform=4",logoPathYct,destPath,"yct-qurCode-"+param.getCatalogId(),true));
        } catch (Exception e) {
            log.error("生成易采通二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setYctQrCodeTitle(param.getYctQrCodeTitle());
        catalogConfig.setYzbPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=4&platform=1");
        catalogConfig.setYzbMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=4&platform=4");
        try {
            String yzbMiniUrl = "pages/mainPackage/index/index?catalogId="+param.getCatalogId()+"&source=4&platform=5&domain="+domainType;//易考通微信小程序码对应的页面url
            catalogConfig.setYzbQrCode(surveyService.getYzbMiniQrCode(yzbMiniUrl, null, param.getCatalogId()));
        } catch (Exception e) {
            log.error("生成易找标二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setYzbQrCodeTitle(param.getYzbQrCodeTitle());
        catalogConfig.setYktPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=3&platform=1");
        catalogConfig.setYktMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=3&platform=4");
        try {
            String yktMiniUrl = "pages/homePage/homePage?catalogId="+param.getCatalogId()+"&source=3&platform=5&domain="+domainType;//易考通微信小程序码对应的页面url
            catalogConfig.setYktQrCode(surveyService.getYktMiniQrCode(yktMiniUrl, null, param.getCatalogId()));
        } catch (Exception e) {
            log.error("生成易考通二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setYktQrCodeTitle(param.getYktQrCodeTitle());
        int result = this.saveCatalogConfig(catalogConfig);
        log.info("保存目录配置数据结果为， result={}, catalogId={}",result,param.getCatalogId());
        if (null != param.getCatalogList()){
            param.getCatalogList().forEach(item1 -> {
                // 第一层(目录)
                SurveyCatalogList catalogList1 = new SurveyCatalogList();
                catalogList1.setCatalogId(param.getCatalogId());
                catalogList1.setSuperId(0);
                catalogList1.setIndexStatus(item1.getIndexStatus());
                catalogList1.setShowIndex(item1.getShowIndex());
                catalogList1.setIconStatus(item1.getIconStatus());
                catalogList1.setIcon(item1.getIcon());
                catalogList1.setTitleStatus(item1.getTitleStatus());
                catalogList1.setTitle(item1.getTitle());
                catalogList1.setInfoStatus(item1.getInfoStatus());
                catalogList1.setInfo(item1.getInfo());
                catalogList1.setType(1);
                catalogList1.setFormId("");
                catalogList1.setChildIndexStatus(item1.getChildIndexStatus());
                int result1 = this.saveCatalogList(catalogList1);
                log.info("第一层数据保存结果，result={}, catalogId={}", result1, param.getCatalogId());
                if (null != item1.getChildren()){
                    item1.getChildren().forEach(item2 -> {
                        SurveyCatalogList catalogList2 = new SurveyCatalogList();
                        catalogList2.setCatalogId(param.getCatalogId());
                        catalogList2.setSuperId(catalogList1.getId());
                        catalogList2.setIndexStatus(item2.getIndexStatus());
                        catalogList2.setShowIndex(item2.getShowIndex());
                        catalogList2.setIconStatus(item2.getIconStatus());
                        catalogList2.setIcon(item2.getIcon());
                        catalogList2.setTitleStatus(item2.getTitleStatus());
                        catalogList2.setTitle(item2.getTitle());
                        catalogList2.setInfoStatus(item2.getInfoStatus());
                        catalogList2.setInfo(item2.getInfo());
                        catalogList2.setType(item2.getType());
                        catalogList2.setFormId(item2.getFormId());
                        catalogList2.setChildIndexStatus(item2.getChildIndexStatus());
                        int result2 = this.saveCatalogList(catalogList2);
                        log.info("第二层数据保存结果，result={}, catalogId={}", result2, param.getCatalogId());
                        if (item2.getType() == 2){
                            if (param.getConfigType() == 1){// 目录选择按照表单设置--修改所有表单的设置为表单
                                surveyService.updateSurveyFormConfig(item2.getFormId(),1);
                            } else if (param.getConfigType() == 2){// 目录选择按照目录配置--修改所有表单的设置为目录
                                surveyService.updateSurveyFormConfig(item2.getFormId(),0);
                            }
                            redisComponent.set("formCatalog:"+item2.getFormId(), param.getCatalogId());// 保存目录表单关联状态
                            redisObjectComponent.del("formResult:"+item2.getFormId());
                        }
                        if (null != item2.getChildren()){
                            item2.getChildren().forEach(item3 -> {
                                SurveyCatalogList catalogList3 = new SurveyCatalogList();
                                catalogList3.setCatalogId(param.getCatalogId());
                                catalogList3.setSuperId(catalogList2.getId());
                                catalogList3.setIndexStatus(item3.getIndexStatus());
                                catalogList3.setShowIndex(item3.getShowIndex());
                                catalogList3.setIconStatus(item3.getIconStatus());
                                catalogList3.setIcon(item3.getIcon());
                                catalogList3.setTitleStatus(item3.getTitleStatus());
                                catalogList3.setTitle(item3.getTitle());
                                catalogList3.setInfoStatus(item3.getInfoStatus());
                                catalogList3.setInfo(item3.getInfo());
                                catalogList3.setType(item3.getType());
                                catalogList3.setFormId(item3.getFormId());
                                catalogList3.setChildIndexStatus(item3.getChildIndexStatus());
                                int result3 = this.saveCatalogList(catalogList3);
                                log.info("第三层数据保存结果，result={}, catalogId={}", result3, param.getCatalogId());
                                if (item3.getType() == 2){
                                    if (param.getConfigType() == 1){// 目录选择按照表单设置--修改所有表单的设置为表单
                                        surveyService.updateSurveyFormConfig(item3.getFormId(),1);
                                    } else if (param.getConfigType() == 2){// 目录选择按照目录配置--修改所有表单的设置为目录
                                        surveyService.updateSurveyFormConfig(item3.getFormId(),0);
                                    }
                                    redisComponent.set("formCatalog:"+item3.getFormId(), param.getCatalogId());// 保存目录表单关联状态
                                    redisObjectComponent.del("formResult:"+item3.getFormId());
                                }
                            });
                        }
                    });
                }
            });
        }
        if (result == 1){
            // 保存操作记录
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getCatalogId());
            operationLog.setDataType(2);
            operationLog.setUserId(users.getUserid());
            operationLog.setActionType(1);
            operationLog.setActionName("创建目录页");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        }
        // 发布状态下进行缓存的更新
        if (catalogConfig.getCatalogStatus() == 1){
            redisObjectComponent.set("catalogConfig:"+param.getCatalogId(), catalogConfig);// 进行目录配置数据的缓存
            SurveyCatalogData catalogData = loadSurveyCatalogData(catalogConfig.getCatalogId());
            // 数据库数据获取完成之后，进行redis存储
            redisObjectComponent.set("catalogResult:"+param.getCatalogId(), catalogData);
        }
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result loadSurveyCatalogConfigData(SurveyCatalogParam param) {
        CatalogConfigData configData = surveyCatalogMapper.loadSurveyCatalogConfigData(param.getCatalogId());
        if (null != configData){
            // 获取用户信息
            configData.setCreateUser(userBaseInfoService.loadUserName(configData.getUserId()));
            // 获取第一层子项
            List<CatalogConfigListData> configListData = surveyCatalogMapper.loadCatalogConfigListData(param.getCatalogId(), 0);
            configListData.forEach(item1-> {
                // 获取表单名称
                if (item1.getType() == 2){
                    item1.setTitle(surveyService.getFormByFormId(item1.getFormId()).getFormTitle());
                }
                List<CatalogConfigListData> configListData2 = surveyCatalogMapper.loadCatalogConfigListData(param.getCatalogId(), item1.getId());
                configListData2.forEach(item2->{
                    // 获取表单名称
                    if (item2.getType() == 2){
                        item2.setTitle(surveyService.getFormByFormId(item2.getFormId()).getFormTitle());
                    }
                    List<CatalogConfigListData> configListData3 = surveyCatalogMapper.loadCatalogConfigListData(param.getCatalogId(), item2.getId());
                    configListData3.forEach(item3 -> {
                        // 获取表单名称
                        if (item3.getType() == 2){
                            item3.setTitle(surveyService.getFormByFormId(item3.getFormId()).getFormTitle());
                        }
                    });
                    item2.setChildren(configListData3);
                });
                item1.setChildren(configListData2);
            });
            configData.setCatalogList(configListData);

        }
        return Result.success(configData);
    }

    @Override
    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
    public Result updateSurveyCatalogConfigData(SurveyCatalogParam param, Users users) {
        CatalogConfigData configData = surveyCatalogMapper.loadSurveyCatalogConfigData(param.getCatalogId());
        int exist = surveyCatalogMapper.loadCatalogIsExist(param.getCatalogId());
        log.info("获取修改的目录ID是否存在， result={}, catalogId={}",exist,param.getCatalogId());
        if (exist == 0) return Result.error(ResponseEnum.CATALOG_NOT_EXIST_ERROR);
        SurveyCatalogConfig catalogConfig = new SurveyCatalogConfig();
        catalogConfig.setCatalogId(param.getCatalogId());
        catalogConfig.setBannerStatus(param.getBannerStatus());
        catalogConfig.setBannerUrl(param.getBannerUrl());
        catalogConfig.setTitle(param.getTitle());
        catalogConfig.setInfoStatus(param.getInfoStatus());
        catalogConfig.setInfoType(param.getInfoType());
        catalogConfig.setInfo(param.getInfo());
        catalogConfig.setConfigType(param.getConfigType());
        catalogConfig.setAuthType(param.getAuthType());
        catalogConfig.setFillType(param.getFillType());
        catalogConfig.setUpdateType(param.getUpdateType());
        catalogConfig.setAuthCodeStatus(param.getAuthCodeStatus());
        catalogConfig.setAuthCode(param.getAuthCode());
        catalogConfig.setAuthUserStatus(param.getAuthUserStatus());
        catalogConfig.setAuthUserErr(param.getAuthUserErr());
        catalogConfig.setTimeStatus(param.getTimeStatus());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            catalogConfig.setStartTime((null == param.getStartTime() || ("").equals(param.getStartTime())) ? null : simpleDateFormat.parse(param.getStartTime()));
            catalogConfig.setEndTime((null == param.getEndTime() || ("").equals(param.getEndTime())) ? null : simpleDateFormat.parse(param.getEndTime()));
        } catch (ParseException e){
            catalogConfig.setStartTime(null);
            catalogConfig.setEndTime(null);
            log.error(e.getMessage());
        }
        catalogConfig.setStartTimeErr(param.getStartTimeErr());
        catalogConfig.setEndTimeErr(param.getEndTimeErr());
        catalogConfig.setCatalogStatus(param.getCatalogStatus());
        catalogConfig.setReleasePlatform(param.getReleasePlatform());
        catalogConfig.setWebPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=1&platform=1");
        catalogConfig.setWebMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=1&platform=4");
        try {
            catalogConfig.setWebQrCode(qrCodeUtils.encode(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=1&platform=4",logoPathWeb,destPath,"web-qurCode-"+param.getCatalogId(),true));
        } catch (Exception e) {
            log.error("生成官网二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setWebQrCodeTitle(param.getWebQrCodeTitle());
        catalogConfig.setYctPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=2&platform=1");
        catalogConfig.setYctMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=2&platform=4");
        try {
            catalogConfig.setYctQrCode(qrCodeUtils.encode(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=2&platform=4",logoPathYct,destPath,"yct-qurCode-"+param.getCatalogId(),true));
        } catch (Exception e) {
            log.error("生成易采通二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setYctQrCodeTitle(param.getYctQrCodeTitle());
        catalogConfig.setYzbPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=4&platform=1");
        catalogConfig.setYzbMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=4&platform=4");
        try {
            String yzbMiniUrl = "pages/mainPackage/index/index?catalogId="+param.getCatalogId()+"&source=4&platform=5&domain="+domainType;//易考通微信小程序码对应的页面url
            catalogConfig.setYzbQrCode(surveyService.getYzbMiniQrCode(yzbMiniUrl, null, param.getCatalogId()));
        } catch (Exception e) {
            log.error("生成易找标二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setYzbQrCodeTitle(param.getYzbQrCodeTitle());
        catalogConfig.setYktPcUrl(pcUrl+"list?catalogId="+param.getCatalogId()+"&source=3&platform=1");
        catalogConfig.setYktMobileUrl(mobileUrl+"list?catalogId="+param.getCatalogId()+"&source=3&platform=4");
        try {
            String yktMiniUrl = "pages/homePage/homePage?catalogId="+param.getCatalogId()+"&source=3&platform=5&domain="+domainType;//易考通微信小程序码对应的页面url
            catalogConfig.setYktQrCode(surveyService.getYktMiniQrCode(yktMiniUrl, null, param.getCatalogId()));
        } catch (Exception e) {
            log.error("生成易考通二维码失败");
            log.error(e.getMessage());
        }
        catalogConfig.setYktQrCodeTitle(param.getYktQrCodeTitle());
        int result = this.updateCatalogConfig(catalogConfig);
        // 清除当前目录下所有用户的权限
        if (param.getConfigType() == 2 &&
                (param.getAuthType() == 1 || param.getAuthCodeStatus() == 1) &&
                (!configData.getAuthType().equals(param.getAuthType()) || !configData.getAuthCodeStatus().equals(param.getAuthCodeStatus()))){
            log.info("目录下所有表单使用此设置，并且登录状态判定/邀请码判定有修改，进行用户权限清除");
            surveyPermissionService.deletePermissionByCatalog(param.getCatalogId());
        }
        log.info("更新目录配置数据结果为， result={}, catalogId={}",result,param.getCatalogId());
        // 因统一更新表单内容，因此需要清除原目录所有列表，然后进行新增
        List<String> formList = surveyCatalogMapper.loadSurveyFormListByList(param.getCatalogId());// 获取原本添加的目录列表，将他们的状态设置为表单状态
        for (String info: formList){
            surveyService.updateSurveyFormConfig(info,1);
            // 清除当前表单的关联状态
            redisComponent.del("formCatalog:"+info);
            redisComponent.del("formPermission:"+info);
            redisObjectComponent.del("form:"+info);// 清除目录详情页接口数据
            redisObjectComponent.del("formResult:"+info);
        }
        int deleteResult = surveyCatalogMapper.deleteCatalogList(param.getCatalogId());
        log.info("清除目录列表内容结果为， deleteResult={}, catalogId={}",deleteResult,param.getCatalogId());
        if (null != param.getCatalogList()){
            param.getCatalogList().forEach(item1 -> {
                // 第一层(目录)
                SurveyCatalogList catalogList1 = new SurveyCatalogList();
                catalogList1.setCatalogId(param.getCatalogId());
                catalogList1.setSuperId(0);
                catalogList1.setIndexStatus(item1.getIndexStatus());
                catalogList1.setShowIndex(item1.getShowIndex());
                catalogList1.setIconStatus(item1.getIconStatus());
                catalogList1.setIcon(item1.getIcon());
                catalogList1.setTitleStatus(item1.getTitleStatus());
                catalogList1.setTitle(item1.getTitle());
                catalogList1.setInfoStatus(item1.getInfoStatus());
                catalogList1.setInfo(item1.getInfo());
                catalogList1.setType(1);
                catalogList1.setFormId("");
                catalogList1.setChildIndexStatus(item1.getChildIndexStatus());
                int result1 = this.saveCatalogList(catalogList1);
                log.info("第一层数据保存结果，result={}, catalogId={}", result1, param.getCatalogId());
                if (null != item1.getChildren()){
                    item1.getChildren().forEach(item2 -> {
                        SurveyCatalogList catalogList2 = new SurveyCatalogList();
                        catalogList2.setCatalogId(param.getCatalogId());
                        catalogList2.setSuperId(catalogList1.getId());
                        catalogList2.setIndexStatus(item2.getIndexStatus());
                        catalogList2.setShowIndex(item2.getShowIndex());
                        catalogList2.setIconStatus(item2.getIconStatus());
                        catalogList2.setIcon(item2.getIcon());
                        catalogList2.setTitleStatus(item2.getTitleStatus());
                        catalogList2.setTitle(item2.getTitle());
                        catalogList2.setInfoStatus(item2.getInfoStatus());
                        catalogList2.setInfo(item2.getInfo());
                        catalogList2.setType(item2.getType());
                        catalogList2.setFormId(item2.getFormId());
                        catalogList2.setChildIndexStatus(item2.getChildIndexStatus());
                        int result2 = this.saveCatalogList(catalogList2);
                        log.info("第二层数据保存结果，result={}, catalogId={}", result2, param.getCatalogId());
                        if (item2.getType() == 2){
                            if (param.getConfigType() == 1){// 目录选择按照表单设置--修改所有表单的设置为表单
                                surveyService.updateSurveyFormConfig(item2.getFormId(),1);
                            } else if (param.getConfigType() == 2){// 目录选择按照目录配置--修改所有表单的设置为目录
                                surveyService.updateSurveyFormConfig(item2.getFormId(),0);
                            }
                            redisComponent.set("formCatalog:"+item2.getFormId(), param.getCatalogId());// 保存目录表单关联状态
                            redisObjectComponent.del("form:"+item2.getFormId());// 清除目录详情页接口数据
                            redisObjectComponent.del("formResult:"+item2.getFormId());
                        }
                        if (null != item2.getChildren()){
                            item2.getChildren().forEach(item3 -> {
                                SurveyCatalogList catalogList3 = new SurveyCatalogList();
                                catalogList3.setCatalogId(param.getCatalogId());
                                catalogList3.setSuperId(catalogList2.getId());
                                catalogList3.setIndexStatus(item3.getIndexStatus());
                                catalogList3.setShowIndex(item3.getShowIndex());
                                catalogList3.setIconStatus(item3.getIconStatus());
                                catalogList3.setIcon(item3.getIcon());
                                catalogList3.setTitleStatus(item3.getTitleStatus());
                                catalogList3.setTitle(item3.getTitle());
                                catalogList3.setInfoStatus(item3.getInfoStatus());
                                catalogList3.setInfo(item3.getInfo());
                                catalogList3.setType(item3.getType());
                                catalogList3.setFormId(item3.getFormId());
                                catalogList3.setChildIndexStatus(item3.getChildIndexStatus());
                                int result3 = this.saveCatalogList(catalogList3);
                                log.info("第三层数据保存结果，result={}, catalogId={}", result3, param.getCatalogId());
                                if (item3.getType() == 2){
                                    if (param.getConfigType() == 1){// 目录选择按照表单设置--修改所有表单的设置为表单
                                        surveyService.updateSurveyFormConfig(item3.getFormId(),1);
                                    } else if (param.getConfigType() == 2){// 目录选择按照目录配置--修改所有表单的设置为目录
                                        surveyService.updateSurveyFormConfig(item3.getFormId(),0);
                                    }
                                    redisComponent.set("formCatalog:"+item3.getFormId(), param.getCatalogId());// 保存目录表单关联状态
                                    redisObjectComponent.del("form:"+item3.getFormId());// 清除目录详情页接口数据
                                    redisObjectComponent.del("formResult:"+item3.getFormId());
                                }
                            });
                        }
                    });
                }
            });
        }
        if (result == 1){
            // 保存操作记录
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getCatalogId());
            operationLog.setDataType(2);
            operationLog.setUserId(users.getUserid());
            operationLog.setActionType(2);
            operationLog.setActionName("修改目录页/修改目录页设置");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        }
        // 发布状态下进行缓存的更新
        if (catalogConfig.getCatalogStatus() == 1){
            redisObjectComponent.set("catalogConfig:"+param.getCatalogId(), catalogConfig);// 进行目录配置数据的缓存
            SurveyCatalogData catalogData = loadSurveyCatalogData(catalogConfig.getCatalogId());
            // 数据库数据获取完成之后，进行redis存储
            redisObjectComponent.set("catalogResult:"+param.getCatalogId(), catalogData);
        }
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result loadSurveyRecycledList(SurveyCatalogParam param) {
        if (null != param.getUserId() && ("").equals(param.getUserId())){
            param.setUserId(userBaseInfoService.loadUserIdByName(param.getUserId()));
        }
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<SurveyRecycledList> list;
        if (param.getType() == 1){// 查询表单
            list = surveyCatalogMapper.loadSurveyFormRecycledList(param);
        } else {// 查询目录
            list = surveyCatalogMapper.loadSurveyCatalogRecycledList(param);
        }
        list.forEach(item -> item.setCreateUser(userBaseInfoService.loadUserName(item.getUserId())));
        PageInfo<SurveyRecycledList> pageList = new PageInfo<>(list);
        return Result.success(pageList);
    }

    @Override
    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
    public Result deleteSurveyCatalogConfigData(SurveyCatalogParam param) {
        // 判定目录状态是否为-1
        int isCanDelete = surveyCatalogMapper.loadCatalogIsCanDelete(param.getCatalogId(), -1);
        if (isCanDelete == 0) return Result.error(ResponseEnum.CATALOG_DELETE_ERROR);
        int deleteCatalogConfig = surveyCatalogMapper.deleteSurveyCatalogConfigData(param.getCatalogId());
        log.info("清除目录配置内容结果为， deleteCatalogConfig={}, catalogId={}",deleteCatalogConfig,param.getCatalogId());
        // 清除list表之前，先将原本list中的状态设置为表单
        List<String> formList = surveyCatalogMapper.loadSurveyFormListByList(param.getCatalogId());// 获取原本添加的目录列表，将他们的状态设置为表单状态
        for (String info: formList){
            surveyService.updateSurveyFormConfig(info,1);
        }
        // 清除list表数据
        int deleteCatalogList = surveyCatalogMapper.deleteCatalogList(param.getCatalogId());
        log.info("清除目录列表内容结果为， deleteCatalogList={}, catalogId={}",deleteCatalogList,param.getCatalogId());
        // 数据下架的时候清除缓存数据
        redisObjectComponent.del("catalogResult:"+param.getCatalogId());// 清除目录详情页接口数据
        redisObjectComponent.del("catalogConfig:"+param.getCatalogId());// 清除目录页配置数据
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result loadSurveyHistoryList(SurveyCatalogParam param) {
        if (null != param.getTitle() && !("").equals(param.getTitle()) && param.getTitleType() == 1){
            param.setTitle(userBaseInfoService.loadUserIdByName(param.getTitle()));
        }
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<SurveyHistoryList> list = surveyCatalogMapper.loadSurveyHistoryList(param);
        list.forEach(item -> item.setCreateUser(userBaseInfoService.loadUserName(item.getUserId())));
        PageInfo<SurveyHistoryList> pageList = new PageInfo<>(list);
        return Result.success(pageList);
    }

    @Override
    public Result cleanSurveyCatalogRecycled(SurveyCatalogParam param) {
        List<String> list = surveyCatalogMapper.loadSurveyCatalogRecycledIdList();
        list.forEach(item ->{
            int deleteCatalogConfig = surveyCatalogMapper.deleteSurveyCatalogConfigData(item);
            log.info("清除目录配置内容结果为， deleteCatalogConfig={}, catalogId={}",deleteCatalogConfig,item);
            // 清除list表之前，先将原本list中的状态设置为表单
            List<String> formList = surveyCatalogMapper.loadSurveyFormListByList(item);// 获取原本添加的目录列表，将他们的状态设置为表单状态
            for (String info: formList){
                surveyService.updateSurveyFormConfig(info,1);
            }
            // 清除list表数据
            int deleteCatalogList = surveyCatalogMapper.deleteCatalogList(item);
            log.info("清除目录列表内容结果为， deleteCatalogList={}, catalogId={}",deleteCatalogList,item);

            // 数据下架的时候清除缓存数据
            redisObjectComponent.del("catalogResult:"+param.getCatalogId());// 清除目录详情页接口数据
            redisObjectComponent.del("catalogConfig:"+param.getCatalogId());// 清除目录页配置数据
        });
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result updateRecoverCatalogConfig(SurveyCatalogParam param) {
        int result = surveyCatalogMapper.updateSurveyCatalogConfigStatus(param.getCatalogId(),0);
        log.info("恢复目录配置内容结果为， result={}, catalogId={}",result,param.getCatalogId());
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result loadSurveyCatalogData(FrontSurveyParam param, HttpServletRequest request) {
        // 请求源referer判定
        String referer = request.getHeader("referer");
        log.info("当前请求的referer={}",referer);
        if (("prod").equals(activeProfile)){
            if (!referer.contains("form.caigou2003.com") && !referer.contains("mform.caigou2003.com")){
                log.error("当前请求的referer不符合规则，不进行请求处理");
                return Result.success(ResponseEnum.SUCCESS);
            }
        }
        // 首先从缓存中获取目录数据，如果能够获取到数据，则直接返回
        SurveyCatalogData catalogData = (SurveyCatalogData) redisObjectComponent.get("catalogResult:"+param.getCatalogId());
        if (null == catalogData){
            // 缓存中获取不到数据，从数据库获取
            catalogData = loadSurveyCatalogData(param.getCatalogId());
            if (null == catalogData) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);
            if (catalogData.getCatalogStatus() == 0) return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
            // 数据库数据获取完成之后，进行redis存储
            log.info("进行目录详情页接口数据redis存储, catalogId={}",param.getCatalogId());
            redisObjectComponent.set("catalogResult:"+param.getCatalogId(), catalogData);
        } else {
            if (catalogData.getCatalogStatus() == 0) return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
        }
        return Result.success(catalogData);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result verifySurveyForm(FrontSurveyParam param, HttpServletRequest request) {
        // 请求源referer判定
        String referer = request.getHeader("referer");
        log.info("当前请求的referer={}",referer);
        if (("prod").equals(activeProfile)){
            if (!referer.contains("form.caigou2003.com") && !referer.contains("mform.caigou2003.com")){
                log.error("当前请求的referer不符合规则，不进行请求处理");
                return Result.success(ResponseEnum.SUCCESS);
            }
        }
        // 如果请求参数不符合加密规则，则不进行处理
        String str = param.getUserId()+param.getDeviceId()+param.getSource()+param.getPlatform()+param.getTimestamp()+param.getRequestIp();// 将所有辨识用户的参数拼接在一起
        String encode1 = Md5Util.MD5_32bit(str, "UTF-8");// 将拼装之后的字符串进行MD5加密
        String encode = Md5Util.MD5_32bit(encode1+"caigou2003.com","UTF-8");
        if (!param.getSign().equals(encode)) {
            log.info("param={}",str);
            log.info("第一遍加密={}",encode1);
            log.info("第二遍加密={}",encode);
            log.error("加密参数验证异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 参数异常判定(时间戳字段，如果超出当前时间5S则认定的是异常请求)
        long nowTime = System.currentTimeMillis()/1000;
        log.info("当前系统时间 time={}",nowTime);
        if (param.getTimestamp() > (nowTime+3) || param.getTimestamp() < (nowTime-2)){
            log.error("请求时间戳字段异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 获取表单主表数据
        SurveyForm form = (SurveyForm) redisObjectComponent.get("form:"+param.getFormId());
        if (null == form){
            log.info("缓存中获取不到form数据，进行mysql获取");
            form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
            if (null != form){
                log.info("进行form主表缓存存储");
                redisObjectComponent.set("form:"+param.getFormId(), form);
            }
        }
        if (null == form) {
            log.info("获取的form数据不存在");
            return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 数据不存在或未发布则不能访问
        }
        if (form.getIsEnable() == 0) {
            log.info("获取的form数据未发布");
            return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
        }
        // 获取表单关联目录的状态
        if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
            log.info("接口中未传递catalogId参数，获取当前表单是否关联了目录");
            param.setCatalogId(redisComponent.get("formCatalog:"+param.getFormId()));
            if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
                log.info("缓存中未获取到catalogId参数，从数据库获取");
                param.setCatalogId(surveyCatalogMapper.loadCatalogIdByForm(param.getFormId()));
                if (null != param.getCatalogId() && !("").equals(param.getCatalogId())){
                    log.info("进行表单目录关联关系的缓存存储");
                    redisComponent.set("formCatalog:"+param.getFormId(),param.getCatalogId());
                }
            }
        }
        // 获取目录配置表数据
        SurveyCatalogConfig config = (SurveyCatalogConfig) redisObjectComponent.get("catalogConfig:"+param.getCatalogId());
        if (null == config){// 当数据库获取数据不为空的时候进行缓存
            config = surveyCatalogMapper.loadSurveyCatalogConfig(param.getCatalogId());
            if (null != config){
                log.info("进行目录配置的缓存存储");
                redisObjectComponent.set("catalogConfig:"+param.getCatalogId(),config);
            }
        }
        // 获取表单配置表数据
        SurveyFormConfig formConfig = (SurveyFormConfig) redisObjectComponent.get("formConfig:"+param.getFormId());
        if (null == formConfig){
            formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            if (null != formConfig){// 当数据库获取数据不为空的时候进行缓存
                log.info("进行表单配置的缓存存储");
                redisObjectComponent.set("formConfig:"+param.getFormId(),formConfig);
            }
        }
        // 封装返回数据
        SurveyFormData form1 = (SurveyFormData) redisObjectComponent.get("formResult:"+param.getFormId());
        if (null == form1){
            form1 = surveyFormMapper.loadSurveyFormData(param.getFormId());
            // 获取表单的二维码列表
            List<SurveyQRListData> qrList = sharePlatformMapper.loadSurveyQRListData(param.getFormId());
            form1.setQrList(qrList);
            // TODO: 2021/6/21 0021 获取表单的广告列表
            // 获取表单的题目列表
            List<SurveyFormQuestionListData> questionList = surveyQuestionMapper.loadSurveyFormQuestionListData(param.getFormId());
            form1.setList(questionList);
            form1.getList().forEach(question -> {
                // 获取题目选项列表
                List<SurveyFormOptionListData> optionList = surveyOptionMapper.loadSurveyFormOptionListData(param.getFormId(),question.getQuestionId());
                question.setList(optionList);
            });
            redisObjectComponent.set("formResult:"+param.getFormId(),form1);
        }
        // 封装头部返回数据
        SurveyFormData surveyFormData = new SurveyFormData();
        surveyFormData.setFormTitle(form1.getFormTitle());
        surveyFormData.setIsDisplayDescription(form1.getIsDisplayDescription());
        surveyFormData.setDescriptionType(form1.getDescriptionType());
        surveyFormData.setFormDescription(form1.getFormDescription());
        surveyFormData.setIsDisplayBanner(form1.getIsDisplayBanner());
        surveyFormData.setFormBanner(form1.getFormBanner());
        surveyFormData.setQrList(form1.getQrList());
        surveyFormData.setBannerList(form1.getBannerList());
        surveyFormData.setFormType(form1.getFormType());
        surveyFormData.setIsForbidGotoCatalog(form1.getIsForbidGotoCatalog());
        surveyFormData.setCatalogId(form1.getCatalogId());
        // 获取权限属性
        int permission;
        boolean permissionResult = false;
        if (null != param.getUserId() && !("").equals(param.getUserId())){
            permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getUserId());
        }
        if (!permissionResult){
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){
                permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getDeviceId());
            }
            if (permissionResult){
                log.info("可以根据deviceId字段获取到权限值");
                permission = 1;
            } else {
                log.info("两个参数都获取不到缓存值，进行mysql数据读取");
                permission = surveyPermissionService.loadSurveyPermission(null == param.getCatalogId() ? "" : param.getCatalogId(),param.getFormId(),param.getUserId(),param.getDeviceId());
                if (permission == 1){
                    log.info("从缓存中获取到了权限，进行权限数据的缓存存储");
                    if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
                    if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
                }
            }
        } else {
            log.info("可以根据userId字段获取到权限值");
            permission = 1;
        }
        // 进行配置数据的判定
        if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
            if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
            log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
            if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                surveyFormData.setStartTime(formConfig.getStartTime());
                surveyFormData.setEndTime(formConfig.getEndTime());
                if (result == 2) {
                    log.error("当前表单目录设置开始时间未到");
                    return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                }
                if (result == 3) {
                    log.error("当前表单目录设置结束时间已到");
                    return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                }
            }
            if (formConfig.getVerifyType() == 0){// 开启登录验证
                if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                    log.error("当前表单目录设置登录验证未通过");
                    return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                }
            }
            if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                if (permission == 0) {
                    log.error("当前表单目录设置邀请码验证未通过");
                    return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                }
            }
        } else {
            if (config.getConfigType() == 1){// 目录设置为按表单需求设置，使用表单配置属性
                if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                log.info("目录设置为按表单需求设置，使用表单配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(formConfig.getStartTime());
                    surveyFormData.setEndTime(formConfig.getEndTime());
                    int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                    }
                }
                if (formConfig.getVerifyType() == 0){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                    log.error("当前表单表单设置邀请码验证未通过");
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            } else {// 目录设置为所有表单使用此设置，使用目录配置属性
                log.info("目录设置为所有表单使用此设置，使用目录配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                // 按照目录页设置判定
                if (config.getTimeStatus() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(config.getStartTime());
                    surveyFormData.setEndTime(config.getEndTime());
                    int result = DateUtil.confineToDate(config.getStartTime(),config.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),config.getStartTimeErr(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),config.getEndTimeErr(),surveyFormData);
                    }
                }
                if (config.getAuthType() == 1){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (config.getAuthCodeStatus() == 1){// 开启邀请码验证
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            }
        }
        // 进行权限判定及填写次数判定
        if (permission == 1) {
            // 提交次数验证
            int userCount = surveySubmitMapper.loadUserAnswerCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户已回答次数
            int todayCount = surveySubmitMapper.loadUserTodayCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户今日回答次数
            if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
                log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
                switch (formConfig.getFillRestriction()){
                    case 1:// 每人填写一次（一共）
                        if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR, surveyFormData);
                        break;
                    case 2:// 每人每天填写两次
                        if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                        break;
                    case 3:// 每人每天填写三次
                        if (todayCount == 1) return Result.error(ResponseEnum.FRONT_SUBMIT_COUNT_ERROR, surveyFormData);
                        if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                        break;
                }
            } else {
                if (config.getConfigType() == 1){
                    if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                    log.info("目录设置为，所有目录内表单使用此设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (formConfig.getFillRestriction()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR, surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount == 1) return Result.error(ResponseEnum.FRONT_SUBMIT_COUNT_ERROR, surveyFormData);
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                    }
                } else {
                    log.info("目录设置为，按表单需求设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (config.getFillType()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR, surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount == 1) return Result.error(ResponseEnum.FRONT_SUBMIT_COUNT_ERROR, surveyFormData);
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                    }
                }
            }
            return Result.success(ResponseEnum.SUCCESS);// 如果有权限数据，则直接返回有权限
        } else {
            if (null == param.getUserId() || null == param.getDeviceId()){
                return Result.success(ResponseEnum.SUCCESS);
            }
            // 登录验证、邀请码验证、时间段验证都通过之后，进行权限数据保存
            SurveyPermission surveyPermission = new SurveyPermission();
            surveyPermission.setCatalogId(null == param.getCatalogId() ? "" : param.getCatalogId());
            surveyPermission.setFormId(param.getFormId());
            surveyPermission.setUserId(param.getUserId());
            surveyPermission.setDeviceId(param.getDeviceId());
            int result = surveyPermissionService.saveSurveyPermission(surveyPermission);
            log.info("权限验证通过，保存用户权限数据 result={}", result);
            if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
            return Result.success(ResponseEnum.SUCCESS);
        }
    }

    public Result verifySurveyFormNeedLogin(FrontSurveyParam param) {
        String formId = param.getFormId();
        SurveyCatalogList surveyCatalogList = surveyCatalogMapper.selectSurveyCatalogListByFormId(formId);
        if(surveyCatalogList!=null){//使用目录页设置
            String catalogId = surveyCatalogList.getCatalogId();
            SurveyCatalogConfig surveyCatalogConfig = surveyCatalogMapper.loadSurveyCatalogConfig(catalogId);
            if(surveyCatalogConfig.getConfigType().intValue()==2){//(1按表单需求设置2所有目录内表单使用此设置)
                log.info("formId={} catalogId={} 按目录页设置获取是否需要登录", formId, catalogId);
                SurveyFormConfigVO surveyFormConfigVO = new SurveyFormConfigVO();
                surveyFormConfigVO.setFormId(formId);
                if(surveyCatalogConfig.getAuthType().intValue()==1){//是否开启登录验证(0无需登录1需要登录)
                    surveyFormConfigVO.setVerifyType(0);
                }else{
                    surveyFormConfigVO.setVerifyType(1);
                }
                return Result.success(surveyFormConfigVO);
            }else{//(1按表单需求设置2所有目录内表单使用此设置)===按表单需求设置
                log.info("formId={} catalogId={} 按表单设置是否需要登录", formId, catalogId);
                SurveyFormConfig formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
                SurveyFormConfigVO surveyFormConfigVO = new SurveyFormConfigVO();
                BeanUtil.copyProperties(formConfig, surveyFormConfigVO);
                return Result.success(surveyFormConfigVO);
            }
        }else{//使用表单设置
            log.info("formId={} 按表单设置是否需要登录", formId);
            SurveyFormConfig formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            SurveyFormConfigVO surveyFormConfigVO = new SurveyFormConfigVO();
            BeanUtil.copyProperties(formConfig, surveyFormConfigVO);
            return Result.success(surveyFormConfigVO);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result verifySurveyFormCode(FrontSurveyParam param, HttpServletRequest request) {
        // 请求源referer判定
        String referer = request.getHeader("referer");
        log.info("当前请求的referer={}",referer);
        if (("prod").equals(activeProfile)){
            if (!referer.contains("form.caigou2003.com") && !referer.contains("mform.caigou2003.com")){
                log.error("当前请求的referer不符合规则，不进行请求处理");
                return Result.success(ResponseEnum.SUCCESS);
            }
        }
        // 获取表单主表数据
        SurveyForm form = (SurveyForm) redisObjectComponent.get("form:"+param.getFormId());
        if (null == form){
            log.info("缓存中获取不到form数据，进行mysql获取");
            form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
            if (null != form){
                log.info("进行form主表缓存存储");
                redisObjectComponent.set("form:"+param.getFormId(), form);
            }
        }
        if (null == form) {
            log.info("获取的form数据不存在");
            return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 数据不存在或未发布则不能访问
        }
        if (form.getIsEnable() == 0) {
            log.info("获取的form数据未发布");
            return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
        }
        // 获取表单关联目录的状态
        if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
            log.info("接口中未传递catalogId参数，获取当前表单是否关联了目录");
            param.setCatalogId(redisComponent.get("formCatalog:"+param.getFormId()));
            if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
                log.info("缓存中未获取到catalogId参数，从数据库获取");
                param.setCatalogId(surveyCatalogMapper.loadCatalogIdByForm(param.getFormId()));
                if (null != param.getCatalogId() && !("").equals(param.getCatalogId())){
                    log.info("进行表单目录关联关系的缓存存储");
                    redisComponent.set("formCatalog:"+param.getFormId(),param.getCatalogId());
                }
            }
        }
        // 获取目录配置表数据
        SurveyCatalogConfig config = (SurveyCatalogConfig) redisObjectComponent.get("catalogConfig:"+param.getCatalogId());
        if (null == config){// 当数据库获取数据不为空的时候进行缓存
            config = surveyCatalogMapper.loadSurveyCatalogConfig(param.getCatalogId());
            if (null != config){
                log.info("进行目录配置的缓存存储");
                redisObjectComponent.set("catalogConfig:"+param.getCatalogId(),config);
            }
        }
        // 获取表单配置表数据
        SurveyFormConfig formConfig = (SurveyFormConfig) redisObjectComponent.get("formConfig:"+param.getFormId());
        if (null == formConfig){
            formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            if (null != formConfig){// 当数据库获取数据不为空的时候进行缓存
                log.info("进行表单配置的缓存存储");
                redisObjectComponent.set("formConfig:"+param.getFormId(),formConfig);
            }
        }
        // 封装返回数据
        SurveyFormData form1 = (SurveyFormData) redisObjectComponent.get("formResult:"+param.getFormId());
        if (null == form1){
            form1 = surveyFormMapper.loadSurveyFormData(param.getFormId());
            // 获取表单的二维码列表
            List<SurveyQRListData> qrList = sharePlatformMapper.loadSurveyQRListData(param.getFormId());
            form1.setQrList(qrList);
            // TODO: 2021/6/21 0021 获取表单的广告列表
            // 获取表单的题目列表
            List<SurveyFormQuestionListData> questionList = surveyQuestionMapper.loadSurveyFormQuestionListData(param.getFormId());
            form1.setList(questionList);
            form1.getList().forEach(question -> {
                // 获取题目选项列表
                List<SurveyFormOptionListData> optionList = surveyOptionMapper.loadSurveyFormOptionListData(param.getFormId(),question.getQuestionId());
                question.setList(optionList);
            });
            redisObjectComponent.set("formResult:"+param.getFormId(),form1);
        }
        // 封装头部返回数据
        SurveyFormData surveyFormData = new SurveyFormData();
        surveyFormData.setFormTitle(form1.getFormTitle());
        surveyFormData.setIsDisplayDescription(form1.getIsDisplayDescription());
        surveyFormData.setDescriptionType(form1.getDescriptionType());
        surveyFormData.setFormDescription(form1.getFormDescription());
        surveyFormData.setIsDisplayBanner(form1.getIsDisplayBanner());
        surveyFormData.setFormBanner(form1.getFormBanner());
        surveyFormData.setQrList(form1.getQrList());
        surveyFormData.setBannerList(form1.getBannerList());
        // 获取权限属性
        int permission;
        boolean permissionResult = false;
        if (null != param.getUserId() && !("").equals(param.getUserId())){
            permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getUserId());
        }
        if (!permissionResult){
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){
                permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getDeviceId());
            }
            if (permissionResult){
                log.info("可以根据deviceId字段获取到权限值");
                permission = 1;
            } else {
                log.info("两个参数都获取不到缓存值，进行mysql数据读取");
                permission = surveyPermissionService.loadSurveyPermission(null == param.getCatalogId() ? "" : param.getCatalogId(),param.getFormId(),param.getUserId(),param.getDeviceId());
                if (permission == 1){
                    log.info("从缓存中获取到了权限，进行权限数据的缓存存储");
                    if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
                    if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
                }
            }
        } else {
            log.info("可以根据userId字段获取到权限值");
            permission = 1;
        }
        if (permission == 1) return Result.success(ResponseEnum.SUCCESS);// 如果有权限数据，则直接返回有权限
        // 根据接口传递或查询回来的目录ID获取目录页配置与表单设置数据
        // 保存用户填写权限
        if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的邀请码
            if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
            log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的邀请码, formId={}", param.getFormId());
            // 判定用户填写的邀请码是否正确
            if (formConfig.getEnableInvite() == 0 || !param.getAuthCode().toLowerCase().equals(formConfig.getInviteCode().toLowerCase())) return Result.error(ResponseEnum.FRONT_CODE_ERROR,surveyFormData);// 邀请码填写错误
        } else {// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
            if (config.getConfigType() == 1){
                if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                log.info("目录设置为，按表单需求设置，使用表单的邀请码, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                // 判定用户填写的邀请码是否正确
                if (formConfig.getEnableInvite() == 0 || !param.getAuthCode().toLowerCase().equals(formConfig.getInviteCode().toLowerCase())) return Result.error(ResponseEnum.FRONT_CODE_ERROR,surveyFormData);// 邀请码填写错误
            } else {
                log.info("目录设置为，按表单需求设置，使用目录的邀请码, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                // 判定用户填写的邀请码是否正确
                if (config.getAuthCodeStatus() == 0 || !param.getAuthCode().toLowerCase().equals(config.getAuthCode().toLowerCase())) return Result.error(ResponseEnum.FRONT_CODE_ERROR,surveyFormData);// 邀请码填写错误
            }
        }
        // 邀请码验证成功--进行权限数据保存
        if (permission == 0){
            // 登录验证、邀请码验证、时间段验证都通过之后，进行权限数据保存
            if (null == param.getUserId() || null == param.getDeviceId()){
                return Result.success(ResponseEnum.SUCCESS);
            }
            SurveyPermission surveyPermission = new SurveyPermission();
            surveyPermission.setCatalogId(null == param.getCatalogId() ? "" : param.getCatalogId());
            surveyPermission.setFormId(param.getFormId());
            surveyPermission.setUserId(param.getUserId());
            surveyPermission.setDeviceId(param.getDeviceId());
            int result = surveyPermissionService.saveSurveyPermission(surveyPermission);
            log.info("权限验证通过，保存用户权限数据 result={}", result);
            if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
        }
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result loadSurveyCatalogStatistics(SurveyCatalogParam param) {
        SurveyCatalogStatistics catalogStatistics = surveyCatalogMapper.loadSurveyCatalogStatistics(param.getCatalogId());
        if (null != catalogStatistics){
            List<SurveyFormStatistics> list = surveyCatalogMapper.loadSurveyFormStatistics(param.getCatalogId());
            catalogStatistics.setList(list);
        }
        return Result.success(catalogStatistics);
    }

    @Override
    public int saveSurveyOperationLog(SurveyOperationLog operationLog) { return surveyCatalogMapper.saveSurveyOperationLog(operationLog); }

    @Override
    public SurveyCatalogConfig loadSurveyCatalogConfig(String catalogId) { return surveyCatalogMapper.loadSurveyCatalogConfig(catalogId); }

    private int saveCatalogConfig(SurveyCatalogConfig config){
        return surveyCatalogMapper.saveCatalogConfig(config);
    }

    private int saveCatalogList(SurveyCatalogList list){ return surveyCatalogMapper.saveCatalogList(list); }

    private int updateCatalogConfig(SurveyCatalogConfig config){ return surveyCatalogMapper.updateCatalogConfig(config); }

    private SurveyCatalogData loadSurveyCatalogData(String catalogId){
        // 没有获取到数据，进行数据库查询逻辑
        SurveyCatalogData catalogData = surveyCatalogMapper.loadSurveyCatalogData(catalogId);
        if (null == catalogData) return null;
        // 下属目录处理
        List<SurveyCatalogListData> list = surveyCatalogMapper.loadSurveyCatalogListData(catalogId,0);// 获取第一层数据
        if (null != list){
            list.forEach(item -> {
                List<SurveyCatalogListData> list2 = surveyCatalogMapper.loadSurveyCatalogListData(catalogId,item.getId());// 获取第二层数据
                if (null != list2){
                    list2.forEach(item2 -> {
                        List<SurveyCatalogListData> list3 = surveyCatalogMapper.loadSurveyCatalogListData(catalogId,item2.getId());// 获取第三层数据
                        if (null != list3) item2.setChild(list3);
                    });
                    item.setChild(list2);
                }
            });
            catalogData.setList(list);
        }
        // TODO: 2021/6/17 0017 广告位列表处理
        // 发布二维码处理
        SurveyCatalogConfig config = surveyCatalogMapper.loadSurveyCatalogConfig(catalogId);
        if (null != config.getReleasePlatform() && !("").equals(config.getReleasePlatform())){
            String[] arr = config.getReleasePlatform().split(",");
            List<SurveyQRListData> qrList = new ArrayList<>();
            for (String s : arr) {
                SurveyQRListData qrListData = new SurveyQRListData();
                switch (s) {
                    case "1":
                        qrListData.setTitle(config.getWebQrCodeTitle());
                        qrListData.setImage(config.getWebQrCode());
                        break;
                    case "2":
                        qrListData.setTitle(config.getYctQrCodeTitle());
                        qrListData.setImage(config.getYctQrCode());
                        break;
                    case "3":
                        qrListData.setTitle(config.getYzbQrCodeTitle());
                        qrListData.setImage(config.getYzbQrCode());
                        break;
                    case "4":
                        qrListData.setTitle(config.getYktQrCodeTitle());
                        qrListData.setImage(config.getYktQrCode());
                        break;
                }
                qrList.add(qrListData);
            }
            catalogData.setQrList(qrList);
        }
        return catalogData;
    }
}
